package com.yst.gateway.monitor.common.validator.web;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.jsp.JspException;
import org.springframework.web.servlet.tags.form.AbstractFormTag;
import org.springframework.web.servlet.tags.form.TagWriter;

/**
 * 根据后台校验生成前端jquery-validator校验代码
 * support：NotNull NotBlank Email Length Pattern Max Min
 * @author sheungxin
 *
 */
@SuppressWarnings("serial")
public class JsValidateTag extends AbstractFormTag{
	
	private String modelClass;
	
	private String formid;
	
	private String groupClass;
	 
	public String getGroupClass() {
		return groupClass;
	}

	public void setGroupClass(String groupClass) {
		this.groupClass = groupClass;
	}

	public String getModelClass() throws JspException {
		String resolvedModelClass = (String) evaluate("modelClass", this.modelClass);
        return (resolvedModelClass != null ? resolvedModelClass : "");
	}

	public void setModelClass(String modelClass) {
		this.modelClass = modelClass;
	}

	public String getFormid() throws JspException {
		String resolvedFormid = (String) evaluate("formid", this.formid);
        return (resolvedFormid != null ? resolvedFormid : "myForm");
	}

	public void setFormid(String formid) {
		this.formid = formid;
	}

	@Override
	protected int writeTagContent(TagWriter tagWriter) throws JspException {
		Object model=null;
		if(getModelClass()!=null){
			try {
				model=Class.forName(getModelClass()).newInstance();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		if(model!=null){
			Map<String, List<String[]>> fieldValidateMap=new HashMap<String, List<String[]>>();
            
            Field[] theFields=model.getClass().getDeclaredFields();
            FieldAnnotationFilter fieldAnnotationFilter=new FieldAnnotationFilter(getRequestContext());
            if(theFields!=null&& theFields.length>0){
                for(Field field : theFields){
                    List<String[]> fieldValidateList=fieldAnnotationFilter.filter(field,groupClass);
                    if(fieldValidateList!=null&&fieldValidateList.size()>0){
                    	fieldValidateMap.put(field.getName(), fieldValidateList);
                    }
                }
            }
            
            if(fieldValidateMap.size()>0){        
                StringBuilder rulesBuilder=new StringBuilder();
                StringBuilder messagesBuilder=new StringBuilder();
                
                rulesBuilder.append("rules:{");
                messagesBuilder.append("messages:{");

                int i=0;
                Iterator<Entry<String, List<String[]>>> iterator=fieldValidateMap.entrySet().iterator();
                while(iterator.hasNext()){
                    Entry<String, List<String[]>> entry=iterator.next();
                    rulesBuilder.append(entry.getKey()).append(":{");
                    messagesBuilder.append(entry.getKey()).append(":{");
                    
                    int j=0;
                    for(String[] array : entry.getValue()){
                        rulesBuilder.append(array[0]).append(":").append(array[1]);
                        messagesBuilder.append(array[0]).append(":\"").append(array[2]).append("\"");

                        if(j<entry.getValue().size()-1){
                            rulesBuilder.append(",");
                            messagesBuilder.append(",");
                        }
                        j++;
                    }
                    
                    rulesBuilder.append("}");
                    messagesBuilder.append("}");

                    if(i<fieldValidateMap.size()-1){
                        rulesBuilder.append(",");
                        messagesBuilder.append(",");
                    }
                    i++;
                }
                
                rulesBuilder.append("},");
                messagesBuilder.append("}");
                tagWriter.startTag("script");
                tagWriter.writeAttribute("type", "text/javascript");
                tagWriter.appendValue("$(function() {");
                tagWriter.appendValue("$(\"#");
                tagWriter.appendValue(getFormid());
                tagWriter.appendValue("\").validate({ignore:'.ignore',errorClass:'help-block',errorElement : 'span',");
                //在失去焦点时验证
                tagWriter.appendValue("onfocusout:function(element){$(element).valid();},");
                tagWriter.appendValue(rulesBuilder.toString());
                tagWriter.appendValue(messagesBuilder.toString());
                tagWriter.appendValue(",highlight:function(element){$(element).parent().addClass('has-error');}");
                tagWriter.appendValue(",success:function(label){label.parent().removeClass('has-error');label.remove();}");
                tagWriter.appendValue(",errorPlacement:function(error, element){element.parent('div').append(error);}");
                tagWriter.appendValue("});");
                tagWriter.appendValue("});");
                tagWriter.endTag(true);
            }
		}
		return EVAL_BODY_INCLUDE;
	}

	@Override
    public void doFinally() {
        super.doFinally();
    }

}
